package com.lastproject.web.bean;

import java.io.IOException;
import java.io.Serializable;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ComponentSystemEvent;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import com.lastproject.dto.CriteriaDTO;
import com.lastproject.dto.DepartmentDTO;
import com.lastproject.dto.ReportDTO;
import com.lastproject.dto.ReportResultDTO;
import com.lastproject.dto.UserDTO;
import com.lastproject.ejb.dao.CheckPermissionDAORemote;
import com.lastproject.ejb.dao.ReportDAORemote;
import com.lastproject.ejb.util.ManipulateFieldsReflection;

@ManagedBean
@ViewScoped
public class OpenReportBean implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 6144391388946618862L;

	@EJB
	ReportDAORemote reportDAO;
	@EJB
	CheckPermissionDAORemote checkPermissionDAO;

	private String error;

	private ReportDTO selectedReport;

	// Selected Columns for Report
	private List<String> selectedColumns;

	// Report Results
	private List<ReportResultDTO> reportResultDTO;

	private List<ReportDTO> reportsList;

	private boolean selectReportPhase;

	private boolean approveDeletion;

	private Integer idToBeDeleted;

	@EJB
	CheckPermissionDAORemote checkPermissionDAORemote;
	
	public void preRenderView(ComponentSystemEvent event) {
        if (!(checkPermissionDAORemote.hasOpenConfidentialReportsRights(true) || checkPermissionDAORemote.hasOpenGeneralReportsRights(true)
        		|| checkPermissionDAORemote.hasCreateConfidentialReportsRights(true) || checkPermissionDAORemote.hasCreateGeneralReportsRights(true))){
        	FacesContext fc = FacesContext.getCurrentInstance();
        	ExternalContext ec = fc.getExternalContext();
        	try {
				ec.redirect("restrictedAccess.xhtml");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        }
    }
	
	@PostConstruct
	public void populateReportList() {

		FacesContext f = FacesContext.getCurrentInstance();
		UserDTO userDTO = (UserDTO) f.getExternalContext().getSessionMap()
				.get("userDTO");

		reportsList = new ArrayList<ReportDTO>();

		if (checkPermissionDAO.hasOpenConfidentialReportsRights(true)) {
			reportsList = reportDAO.getAllReportsForUser(userDTO);
		} else if (checkPermissionDAO.hasOpenGeneralReportsRights(true)) {
			reportsList = reportDAO.getGeneralReportsForUser(userDTO);
		}

		selectedColumns = new ArrayList<String>();
		selectReportPhase = false;
		approveDeletion = false;
		approveDeletion = false;
		idToBeDeleted = null;
	}

	public OpenReportBean() {

	}

	public boolean isApproveDeletion() {
		return approveDeletion;
	}

	public void setApproveDeletion(boolean approveDeletion) {
		this.approveDeletion = approveDeletion;
		if (approveDeletion)
			this.idToBeDeleted = Integer.parseInt(FacesContext
					.getCurrentInstance().getExternalContext()
					.getRequestParameterMap().get("reportID"));
	}

	public String getError() {
		return error;
	}

	public void setError(String error) {
		this.error = error;
	}

	public ReportDTO getSelectedReport() {
		return selectedReport;
	}

	public List<String> getSelectedColumns() {
		return selectedColumns;
	}

	public void setSelectedColumns(List<String> selectedColumns) {
		this.selectedColumns = selectedColumns;
	}

	public List<ReportResultDTO> getReportResultDTO() {
		return reportResultDTO;
	}

	public void setReportResultDTO(List<ReportResultDTO> reportResultDTO) {
		this.reportResultDTO = reportResultDTO;
	}

	public List<ReportDTO> getReportsList() {
		return reportsList;
	}

	public boolean isSelectReportPhase() {
		return selectReportPhase;
	}

	public String openReport() {
		try {
			int selectedReportID = Integer.parseInt(FacesContext
					.getCurrentInstance().getExternalContext()
					.getRequestParameterMap().get("reportID"));
			selectedReport = reportDAO.findById(selectedReportID);
			String[] columns = selectedReport.getSelClause().split(",");
			selectedColumns = Arrays.asList(columns);
			reportResultDTO = reportDAO.getReportResults(selectedReport);
			selectReportPhase = true;
			return null;
		} catch (Exception e) {
			return error = "Report could not be opened ";
		}
	}

	public String deleteReport() {
		try {
			selectedReport = reportDAO.findById(idToBeDeleted);
			reportDAO.remove(selectedReport);
			error = "Report succesfully removed";
			idToBeDeleted = null;
			approveDeletion = false;
			return "manageReports.xhtml";
		} catch (Exception e) {
			return error = "Report could not be opened";
		}
	}

	public void exportToXls() {

		String filename = "reportExport.xls";

		int colNumber = selectedColumns.size();
		try {
			HSSFWorkbook wb = new HSSFWorkbook();
			HSSFSheet sheet = wb.createSheet(filename);

			HSSFRow row = sheet.createRow(0);
			// Creating export file header
			for (int i = 0; i < colNumber; i++) {
				row.createCell(i).setCellValue(selectedColumns.get(i));
			}

			SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
					"yyyy/MM/dd");
			DecimalFormat myFormatter = new DecimalFormat("######.##");

			row.createCell(colNumber + 2).setCellValue(
					"Report Name: " + selectedReport.getName());
			row.createCell(colNumber + 3)
					.setCellValue(
							"Report Date: "
									+ simpleDateFormat.format(selectedReport
											.getDate()));

			// Populating table of exported file
			for (int i = 0; i < reportResultDTO.size(); i++) {
				row = sheet.createRow(i + 1);

				// Populating a row
				for (int j = 0; j < selectedColumns.size(); j++) {
					switch (selectedColumns.get(j)) {
					case "firstname":
						row.createCell(j).setCellValue(
								reportResultDTO.get(i).getFirstname());
						break;
					case "lastname":
						row.createCell(j).setCellValue(
								reportResultDTO.get(i).getLastname());
						break;
					case "dob":
						if (reportResultDTO.get(i).getDob() != null) {
							String dobString = simpleDateFormat
									.format(reportResultDTO.get(i).getDob());
							row.createCell(j).setCellValue(dobString);
						} else
							row.createCell(j).setCellValue("");
						break;
					case "personalEmail":
						row.createCell(j).setCellValue(
								reportResultDTO.get(i).getPersonalEmail());
						break;
					case "personalPhone":
						row.createCell(j).setCellValue(
								reportResultDTO.get(i).getPersonalPhone());
						break;
					case "employmentDate":
						if (reportResultDTO.get(i).getEmploymentDate() != null) {
							String employmentDateString = simpleDateFormat
									.format(reportResultDTO.get(i)
											.getEmploymentDate());
							row.createCell(j)
									.setCellValue(employmentDateString);
						} else
							row.createCell(j).setCellValue("");
						break;
					case "medCheckUpDate":
						if (reportResultDTO.get(i).getMedCheckUpDate() != null) {
							String medCheckUpDateString = simpleDateFormat
									.format(reportResultDTO.get(i)
											.getMedCheckUpDate());
							row.createCell(j)
									.setCellValue(medCheckUpDateString);
						} else
							row.createCell(j).setCellValue("");
						break;
					case "employmentType":
						row.createCell(j).setCellValue(
								reportResultDTO.get(i).getEmploymentType());
						break;
					case "position":
						row.createCell(j).setCellValue(
								reportResultDTO.get(i).getPosition());
						break;
					case "workEmail":
						row.createCell(j).setCellValue(
								reportResultDTO.get(i).getWorkEmail());
						break;
					case "workPhone":
						row.createCell(j).setCellValue(
								reportResultDTO.get(i).getWorkPhone());
						break;
					case "careerLevel":
						row.createCell(j).setCellValue(
								reportResultDTO.get(i).getCareerLevel());
						break;
					case "salary":
						if (reportResultDTO.get(i).getSalary() != null) {
							String salaryString = myFormatter
									.format(reportResultDTO.get(i).getSalary());
							row.createCell(j).setCellValue(salaryString);
						} else
							row.createCell(j).setCellValue("");
						break;
					case "varpart":
						if (reportResultDTO.get(i).getVarPart() != null) {
							String varpartString = myFormatter
									.format(reportResultDTO.get(i).getVarPart());
							row.createCell(j).setCellValue(varpartString);
						} else
							row.createCell(j).setCellValue("");
						break;
					case "applyingFor":
						row.createCell(j).setCellValue(
								reportResultDTO.get(i).getApplyingFor());
						break;
					case "domain":
						row.createCell(j).setCellValue(
								reportResultDTO.get(i).getDomain());
						break;
					case "email":
						row.createCell(j).setCellValue(
								reportResultDTO.get(i).getEmail());
						break;
					case "phonenr":
						row.createCell(j).setCellValue(
								reportResultDTO.get(i).getPhonenr());
						break;
					case "statut":
						row.createCell(j).setCellValue(
								reportResultDTO.get(i).getStatut());
						break;
					case "department":
						row.createCell(j).setCellValue(
								reportResultDTO.get(i).getDepartment()
										.getName());
						break;
					}
				} // End of populating each row

			} // End of populating table

			FacesContext context = FacesContext.getCurrentInstance();
			HttpServletResponse res = (HttpServletResponse) context
					.getExternalContext().getResponse();
			res.setContentType("application/vnd.ms-excel");
			res.setHeader("Content-disposition", "attachment;filename="
					+ filename);

			ServletOutputStream out = res.getOutputStream();
			wb.write(out);
			out.flush();
			out.close();
			FacesContext.getCurrentInstance().responseComplete();

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public String goBack() {
		this.selectReportPhase = false;
		return "manageReports.xhtml";
	}

	public Integer getIdToBeDeleted() {
		return idToBeDeleted;
	}

	public void setIdToBeDeleted(Integer idToBeDeleted) {
		this.idToBeDeleted = idToBeDeleted;
	}

	public String header(String col) {
		switch (col) {
		case "firstname":
			return "Firstname";
		case "lastname":
			return "Lastname";
		case "dob":
			return "Date of birth";
		case "personalEmail":
			return "Personal Email";
		case "personalPhone":
			return "Personal Phone";
		case "employmentDate":
			return "Employment Date";
		case "medCheckUpDate":
			return "Medical Checkup";
		case "employmentType":
			return "Employment Type";
		case "position":
			return "Position";
		case "workEmail":
			return "Work Email";
		case "workPhone":
			return "Work Phone";
		case "careerLevel":
			return "Career Level";
		case "salary":
			return "Salary";
		case "varPart":
			return "Variable Part";
		case "applyingFor":
			return "Applying for";
		case "domain":
			return "Domain";
		case "email":
			return "Email";
		case "phonenr":
			return "Phone nr";
		case "statut":
			return "Statut";
		case "department":
			return "Department";
		default:
			return "";
		}

	}

}
